iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
自我挑戰組

Unit Test 學習路系列 第 19

Day 18: React Testing Library - queryBy** 與 queryAllBy**

  • 分享至 

  • xImage
  •  

昨天統整了 getBy**getAllBy** 可以協助我們取到 指定 DOM 節點。
今天來談談 queryBy**queryAllBy**,我們會在什麼時間使用到。

queryBy**

  • 用途:
    取得指定的 DOM node,如果符合條件,回傳該元素; 如果沒有符合、或超過一個符合條件,回傳 null
  • 何時會用到:
    當我們要測試某個條件下,該節點是否會顯示,但不希望測試報錯的情況。
    (我們使用 getBy** 時,如果沒有符合、或超過一個符合條件,會直接噴錯)
  • 舉例:
    畫面上,如果使用者已登入,顯示 <LogOutBtn />; 如果使用者未登入,顯示 <LogInBtn />
export default function Applications(){
    const [isLoggedIn, setIsLoggedIn] = useState(false);

    return(
        <>
            {   isLoggedIn
                ? <Hobbies hobbies={["Sleeping", "Cooking", "Eating"]}/>
                : null
            }
        </>
    )
}

撰寫測試:

describe("Logging", () => {
    // 檢查 <LogInBtn /> 是否存在
    test("Render LogIn Button correctlly!", () => {
        render(<Applications />);

        const logInBtn = screen.getByRole("button", {
            name: "Log In"
        });
        expect(logInBtn).toBeInTheDocument();
    });

    // 檢查 <LogOutBtn /> 是否存在
    test("Not render LogOut Button!", () => {
        render(<Applications />);

        const logInBtn = screen.getByRole("button", {
            name: "Log Out"
        });
        expect(logInBtn).not.toBeInTheDocument();
    });
});

測試結果:
FAIL src/components/logging/logging.test.tsx
● Logging › Not render LogOut Button!
TestingLibraryElementError: Unable to find an accessible element with the role "button" and name "Log Out"

因為使用 getByRole 的方法,在畫面上找不到 指定 DOM 節點,會直接報錯,測試會無法繼續。

修改測試,將 getByRole 改成 queryByRole :

describe("Logging", () => {
    ...
    // 檢查 <LogOutBtn /> 是否存在
    test("Not render LogOut Button!", () => {
        render(<Applications />);

        const logInBtn = screen.queryByRole("button", {
            name: "Log Out"
        });
        expect(logInBtn).not.toBeInTheDocument();
    });
});

測試結果:
PASS src/components/logging/logging.test.tsx
使用 queryByRole 的方法,在畫面上找不到 指定 DOM 節點,回傳 null,可以作為檢查該 DOM 節點 在特定條件下不應該出現。


queryAllBy**

  • 舉例:
export default function Applications(){
    const [isLoggedIn, setIsLoggedIn] = useState(false);

    return(
        <>
            {   isLoggedIn
                ? <Hobbies hobbies={["Sleeping", "Cooking", "Eating"]}/>
                : null
            }
        </>
    )
}

撰寫測試:

describe("Hobbies By Logging State", () => {
    // 檢查 <li> 多個節點
    test("Render Listitems correctlly!", () => {
        render(<Applications />);

        const listItemElements = screen.getAllByRole("listitem");
        expect(listItemElements).toHaveLength(0);
    });
});

測試結果:
FAIL src/components/hobbies/hobbies.test.tsx
● Hobbies By Logging State › Render Listitems correctlly!
TestingLibraryElementError: Unable to find an accessible element with the role "listitem"

修改測試,將 getAllByRole 改成 queryAllByRole :

describe("Hobbies By Logging State", () => {
    // 檢查 <li> 多個節點
    test("Render Listitems correctlly!", () => {
        render(<Applications />);

        const listItemElements = screen.queryAllByRole("listitem");
        expect(listItemElements).toHaveLength(0);
    });
});

參考資源


上一篇
Day 17: React Testing Library - getAllBy** 與 其他
下一篇
Day 19: React Testing Library - findBy** 與 findAllBy**
系列文
Unit Test 學習路31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言